home *** CD-ROM | disk | FTP | other *** search
- {$A+,B-,D+,E-,F-,G+,I-,L+,N-,O-,R+,S+,V-,X+,M 4096,0,655360
- NSORT version 3. Uses Shell sort instead of Insertion sort. Damn fast, still
- handles all that can fit into conventional memory.
- }
-
- uses dos;
-
- type
- pstring=^string;
- prec=^rec;
- rec=record
- s:pstring;
- n:prec;
- end;
-
- const
- rsize=sizeof(rec);
-
- var
- linet,linec:longint; {line total, current}
- list,start,lstptr,next:prec;
- {list,
- start of sorting zone,
- list stroller,
- next item to be swapped}
- infile,outfile,tmpline:string; {file names, input line}
- textf:text; {input/output file variable}
- tbuf:array [1..8192] of char; {text file buffer}
-
- procedure progress;
- var
- ctr,indicator:byte; {show graphically, how many blocks}
- begin
- inc(linec); {increase current line}
- indicator:=100*linec div linet; {get %}
- write(indicator:5,'% ');
- indicator:=indicator div 5; {get 1/20th portion}
- for ctr:=1 to 20 do
- if ctr<=indicator then write('o') {o=5% done, .=5% remaining}
- else write('.');
- write(^m); {only carriage return: not new line too}
- end;
-
- procedure TheEnd; far;
- begin
- exitproc:=nil;
- case exitcode of
- 1:writeln('Input file not found');
- 2:writeln('Can''t open input file');
- 3:writeln('Out of memory');
- 4:writeln('Can''t create output file');
- 5:writeln('Can''t finish output file');
- 6:writeln('Insufficient disk space');
- end;
- writeln('NSort version 3.');
- writeln('NetRunner of Assassin Technologies. Lum''s Place 613 531 1911');
- end;
-
- procedure checkfit;
- var
- f:file;
- size:longint;
- drive:string[1];
- begin
- if infile<>outfile then begin
- assign(f,infile);
- reset(f,1);
- size:=filesize(f);
- drive:=fexpand(outfile);
- dec(drive[1],byte('A')-1);
- if size>diskfree(byte(drive[1])) then halt(6);
- end;
- end;
-
- procedure showhelp;
- begin
- writeln('Heavy duty sorter. Syntax: NSORT infile outfile | /s');
- writeln('/s= use input name as output.');
- writeln('Batch file exit codes:');
- writeln('1 Input file not found');
- writeln('2 Can''t open input file');
- writeln('3 Out of memory');
- writeln('4 Can''t create output file');
- writeln('5 Can''t finish output file');
- writeln('6 Insufficient disk space');
- halt;
- end;
-
- procedure swap(var p1,p2:pstring);
- var tmpptr:pstring;
- begin
- tmpptr:=p1;
- p1:=p2;
- p2:=tmpptr;
- end;
-
- Function upstr(s:string):string;
- var c:byte;
- begin
- if length(s)>0 then for c:=1 to length(s) do s[c]:=upcase(s[c]);
- upstr:=s;
- end;
-
- Function fexist(fn:pathstr):boolean;
- var f:file; it:word;
- begin
- assign(f,fn);
- getfattr(f,it);
- fexist:=doserror=0;
- doserror:=0;
- end;
-
- function malloc(var p; ram:word):boolean;
- begin
- if (maxavail>=ram) then begin
- if ram=0 then pointer(p):=nil {0 is OK but not an allocation}
- else getmem(pointer(p),ram); {allocate if RAM > 0}
- malloc:=true
- end
- else begin {not enough RAM}
- malloc:=false;
- pointer(p):=nil
- end
- end;
-
- begin
- exitproc:=@TheEnd; {set exit procedure}
- linec:=0; {init}
- linet:=0;
-
- if paramcount=0 then showhelp; {show online help, no cmd line}
-
- {set input/output files}
-
- infile:=upstr(paramstr(1));
- outfile:=upstr(paramstr(2));
- if outfile='/S' then outfile:=infile; {/s as output file = same name}
-
- if not fexist(infile) then halt(1); {stop if input doesn't exist}
-
- checkfit; {if output file too large/not enough space, this finds it}
-
- assign(textf,infile); {set input file}
- settextbuf(textf,tbuf); {set text buffer for speed}
-
- reset(textf);
- if ioresult<>0 then halt(2); {stop if error opening file}
-
- list:=nil;
-
- {input file processing}
-
- while not eof(textf) do begin
- readln(textf,tmpline); {get input}
- inc(linet); {total line count, setup in loop}
- if list=nil then begin {if list doesn't exist yet}
- if not malloc(pointer(list),rsize) then halt(3); {allocate linked list rec}
- next:=list; {next used to advance linked list}
- end
- else begin {current piece of list is not 1st}
- if not malloc(pointer(next^.n),rsize) then halt(3); {alloc linked list node}
- next:=next^.n; {advance placeholder}
- end;
- if not malloc(pointer(next^.s),length(tmpline)+1) then halt(3); {allocate
- line} move(tmpline,next^.s^,length(tmpline)+1);
- next^.n:=nil; {set list end = nil}
- end;
- close(textf); {close input file}
-
- {sorting begins here}
-
- start:=list;
- while start<>nil do begin
- next:=start;
- lstptr:=start;
- while lstptr<>nil do begin
- if lstptr^.s^ < next^.s^ then next:=lstptr;
- lstptr:=lstptr^.n; {advance list pointer}
- end;
- swap(start^.s,next^.s);
- progress;
- start:=start^.n; {advance start zone boundary, gradual reduction}
- end;
- writeln;
-
- {file output after complete sorting}
-
- lstptr:=list;
- assign(textf,outfile);
- rewrite(textf);
- if ioresult<>0 then halt(4);
- while lstptr<>nil do begin
- writeln(textf,lstptr^.s^);
- if ioresult<>0 then begin
- close(textf);
- halt(5);
- end;
- lstptr:=lstptr^.n;
- end;
- close(textf);
- end.